package com.proactive.webapp.controller;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.security.NoSuchAlgorithmException;
import java.util.Date;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import org.apache.commons.lang.StringEscapeUtils;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.view.RedirectView;

import com.proactive.webapp.dao.CourseDAO;
import com.proactive.webapp.dao.DesignDAO;
import com.proactive.webapp.dao.MemberDAO;
import com.proactive.webapp.dao.MenuDAO;
import com.proactive.webapp.entity.Member;
import com.proactive.webapp.entity.Menu;
import com.proactive.webapp.util.AwsUtil;
import com.proactive.webapp.util.CompressImage;
import com.proactive.webapp.util.DateConversion;
import com.proactive.webapp.util.FacebookConnection;
import com.proactive.webapp.util.FacebookGraphProfile;
import com.proactive.webapp.util.FileUtil;
import com.proactive.webapp.util.HtmlUtil;
import com.proactive.webapp.util.Mail;
import com.proactive.webapp.util.MenuUtil;
import com.proactive.webapp.util.SecurityMD5;
import com.proactive.webapp.util.UUIDGenerator;
import com.proactive.webapp.util.entity.Facebook;

@Controller
public class MemberController {
	ApplicationContext context =  new ClassPathXmlApplicationContext("spring-module.xml");
	
	@RequestMapping(value = "/login", method = RequestMethod.GET)
	public ModelAndView getLogin(HttpServletRequest request, HttpSession session) {
		ModelAndView model = new ModelAndView();
		Member loginMember = (Member)session.getAttribute("loginMember");
		if(loginMember == null){
			if(session.getAttribute("errorMsg") != null){
				String errorMsg = session.getAttribute("errorMsg").toString();
				session.removeAttribute("errorMsg");
				model.addObject("errorMsg", errorMsg);
			}
			
			List<Menu> menuList = MenuUtil.getList(((MenuDAO)context.getBean("menuDAO")).getList(), 0);

			model.addObject("menuList", menuList);
			model.setViewName("login");
		}
		else
			model.setViewName("redirect:/");
		return model;
	}

	@RequestMapping(value = "/checkLogin", method = RequestMethod.POST)
	public ModelAndView checkLogin(@ModelAttribute Member member, HttpSession session, HttpServletRequest request) throws IOException {
		ModelAndView model = new ModelAndView();
		SecurityMD5 securityMD5 = new SecurityMD5();
		MemberDAO memberDAO = (MemberDAO)context.getBean("memberDAO");
		try {
			member.setPassword(securityMD5.encryptWords(member.getPassword()));
		} catch (NoSuchAlgorithmException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		member = memberDAO.checkLogin(member);
		if(member.isLogin()){
			session.setAttribute("loginMember", member);
			model.setViewName("redirect:"+request.getHeader("referer"));
		}
		else{
			session.setAttribute("errorMsg", "無效的帳號密碼或未驗證");
			model.setViewName("redirect:/login");
		}
		return model;
	}
	
	
	@RequestMapping(value = "/fbCheckLogin", method = RequestMethod.GET)
	public ModelAndView fbCheckLogin(HttpServletRequest request, HttpSession session) {
		ModelAndView model = new ModelAndView();
		String code = request.getParameter("code");
		String next = session.getAttribute("next") == null ? "/" : session.getAttribute("next").toString();
		session.removeAttribute("next");
        if(code != null){
			FacebookConnection fbConn = new FacebookConnection();
	        String accessToken = fbConn.getAccessToken(code);
	        FacebookGraphProfile graphProfile = new FacebookGraphProfile(accessToken);
	        String fbGraph = graphProfile.getGraph();
	        Facebook facebook = graphProfile.getGraphProfile(fbGraph);
	        if(facebook.isVerified()){
	        	MemberDAO memberDAO = (MemberDAO)context.getBean("memberDAO"); 
	        	Member member = new Member();
	        	member.setAccount(facebook.getId());
	        	member = memberDAO.checkFacebookAccount(member);
	        	
	        	if(!member.isLogin()){
	        		member.setName(facebook.getName());
		        	member.setEmail(facebook.getEmail());
		        	member.setPhotoPath(facebook.getPhoto());
		        	member.setFacebook(facebook.getFacebookUrl());
	        		memberDAO.insertByFacebook(member);
	        		member = memberDAO.get(member);
	        	}
	        	
				session.setAttribute("loginMember", member);
		    	model.setViewName("redirect:"+next);
	        }
	        else
		    	model.setViewName("redirect:"+next);
        }
        else
	    	model.setViewName("redirect:"+next);
		return model;
		
	}
	
	@RequestMapping(value="/fbLogin", method=RequestMethod.GET)
	public RedirectView redirectOAuth(HttpServletRequest request, HttpSession session){
		//RedirectView 導到外部頁面
		FacebookConnection fbConn = new FacebookConnection();
		String referer = request.getHeader("referer");
		session.setAttribute("next", referer);
		
		return new RedirectView(fbConn.getOAuthUrl());
	}
	
	@RequestMapping(value = "/logout", method = RequestMethod.GET)
	public ModelAndView logout(HttpServletRequest request, HttpSession session) {
		ModelAndView model = new ModelAndView("redirect:"+request.getHeader("referer"));
		request.getSession().invalidate();
		return model;
	}
	
	@RequestMapping(value = "/register", method = RequestMethod.GET)//註冊會員
	public ModelAndView register(HttpSession session){
		ModelAndView model = new ModelAndView();
		Member loginMember = (Member)session.getAttribute("loginMember");
		if(loginMember != null)
			model.setViewName("redirect:/");
		else{			
			List<Menu> menuList = MenuUtil.getList(((MenuDAO)context.getBean("menuDAO")).getList(), 0);
			model.addObject("menuList", menuList);
			model.setViewName("register");
		}
		return model;
	}
	
	@RequestMapping(value = "/checkAccount", method = RequestMethod.POST)
	public @ResponseBody boolean checkAccount(String account){
		MemberDAO memberDAO = (MemberDAO)context.getBean("memberDAO");
		boolean flag = memberDAO.checkAccount(account);
		return flag;
	}
	
	@RequestMapping(value = "/addMember", method = RequestMethod.POST)
	public ModelAndView addMember(Member member, HttpServletRequest request, HttpSession session){
		ModelAndView model = new ModelAndView();
		MemberDAO memberDAO = (MemberDAO)context.getBean("memberDAO");
		SecurityMD5 securityMD5 = new SecurityMD5();
//		member.setRegisterNO(UUIDGenerator.getUUID());
		try {
			member.setPassword(securityMD5.encryptWords(member.getPassword()));
		} catch (NoSuchAlgorithmException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		member.setRegisterNO("");
		member.setEmail(member.getAccount());
		memberDAO.insert(member);
		Member loginMember = new Member();
		loginMember.setAccount(member.getAccount());
		loginMember = memberDAO.get(loginMember);
		session.setAttribute("loginMember", loginMember);
		model.setViewName("redirect:/aboutme?id"+loginMember.getMemberNO());
//		HtmlUtil htmlUtil = new HtmlUtil();
//		String subject = "Proactive：會員註冊驗證";
//		String message = "";
//		try {
//			message = htmlUtil.htmlToString(request.getServletContext().getRealPath("html/register.html"));
//		} catch (FileNotFoundException e) {
//			// TODO Auto-generated catch block
//			e.printStackTrace();
//		}
//		Mail mail = new Mail();
//		message = message.replaceAll("link_url", "http://www.proactive.tw/active?aid="+member.getRegisterNO());
//		message = message.replaceAll("user_name", member.getName());
//		mail.sendMail(subject, member.getAccount(), message);
		return model;
	}
	
	@RequestMapping(value = "/register2", method = RequestMethod.GET)
	public ModelAndView register2Cont(){
		ModelAndView model = new ModelAndView("register2");		
		List<Menu> menuList = MenuUtil.getList(((MenuDAO)context.getBean("menuDAO")).getList(), 0);
		model.addObject("menuList", menuList);
		model.addObject("flag", true);
		return model;
	}
	
	@RequestMapping(value = "/active", method = RequestMethod.GET)
	public ModelAndView modiMemberStatus(String aid, HttpSession session){
		ModelAndView model = new ModelAndView();
		MemberDAO memberDAO = (MemberDAO)context.getBean("memberDAO");
		Member member = new Member();
		member.setRegisterNO(aid);
		member = memberDAO.getByRegisterNO(member);
		if(member.getAccount()!=null && member.getStatus()==0){
			memberDAO.updateStatus(member);
			session.setAttribute("loginMember", member);
			model.addObject("flag", true);
		}
		else
			model.addObject("flag", false);

		List<Menu> menuList = MenuUtil.getList(((MenuDAO)context.getBean("menuDAO")).getList(), 0);
		model.addObject("menuList", menuList);
		model.setViewName("register3");
		return model;
	}
	

	@RequestMapping(value = "/aboutme", method = RequestMethod.GET)
	public ModelAndView getMember(HttpServletRequest request, HttpSession session){
		ModelAndView model = new ModelAndView();
		Member loginMember = (Member)session.getAttribute("loginMember");
		if (request.getParameter("id") != null) {
			MemberDAO memberDAO = (MemberDAO) context.getBean("memberDAO");
			CourseDAO courseDAO = (CourseDAO) context.getBean("courseDAO");
			DesignDAO designDAO = (DesignDAO) context.getBean("designDAO");
			Member member = new Member();			
			String loginAccount = "";
			
			String memberNO = request.getParameter("id");
			
			member.setMemberNO(memberNO);
			member = memberDAO.getByMemberNO(member);//用memberNO取得memberAccount
			if(member.getAccount()!=null){
				if(loginMember != null){
					member = memberDAO.getByLogin(member, loginMember.getAccount());//取得member資料
					loginAccount = loginMember.getAccount();
				}

				
				
				member.setCourseCount(courseDAO.countTotalByMember(member.getAccount()));
				member.setDesignCount(designDAO.countTotalByMember(member.getAccount()));
				member.setContent(StringEscapeUtils.unescapeHtml(member.getContent()));
				

				List<Menu> menuList = MenuUtil.getList(((MenuDAO)context.getBean("menuDAO")).getList(), 0);
				
				//set model
				model.addObject("member", member);
				model.addObject("menuList", menuList);
				model.setViewName(loginMember!=null?"aboutme1":"aboutme2");
			}
			else
				model.setViewName("redirect:/");
		} 
		else
			model.setViewName(loginMember!=null?"redirect:/aboutme?id="+loginMember.getMemberNO():"redirect:/login");

		return model;
	}
	
	@RequestMapping(value = "/modiAboutmeCont", method = RequestMethod.GET)
	public ModelAndView modiAboutmeCont(HttpServletRequest request, HttpSession session){
		ModelAndView model = new ModelAndView();
		Member loginMember = (Member)session.getAttribute("loginMember");
		
		if(loginMember != null){
			MemberDAO memberDAO = (MemberDAO) context.getBean("memberDAO");
			CourseDAO courseDAO = (CourseDAO) context.getBean("courseDAO");
			DesignDAO designDAO = (DesignDAO) context.getBean("designDAO");
			Member member = new Member();
			member.setAccount(loginMember.getAccount());			
			member = memberDAO.get(member);
			member.setCourseCount(courseDAO.countTotalByMember(member.getAccount()));
			member.setDesignCount(designDAO.countTotalByMember(member.getAccount()));

			List<Menu> menuList = MenuUtil.getList(((MenuDAO)context.getBean("menuDAO")).getList(), 0);
			
			model.addObject("member", member);
			model.addObject("menuList", menuList);
			model.setViewName("modiAboutme");
		}
		else
			model.setViewName("redirect:/login");
		
		
		return model;
	}
	
	@RequestMapping(value = "/modiAboutme", method = RequestMethod.POST)
	public ModelAndView modiAboutme(@ModelAttribute Member member, HttpSession session, HttpServletRequest request) {
		Member loginMember = (Member)session.getAttribute("loginMember");
		ModelAndView model = new ModelAndView();
		if(loginMember != null){
			MemberDAO memberDAO = (MemberDAO) context.getBean("memberDAO");
			Member oldMember = new Member();
			oldMember.setAccount(loginMember.getAccount());
			oldMember = memberDAO.get(oldMember);
			member.setAccount(loginMember.getAccount());
			if(member.getPhoto().getSize() > 0){
				//new AWS
				AwsUtil awsUtil = new AwsUtil();
		        awsUtil.setPropertyPath(request.getServletContext().getRealPath("../AwsCredentials.properties"));
		        awsUtil.getInstance();
		        
				String path1 = session.getServletContext().getRealPath("resources/image/picture");
				DateConversion dateConversion = new DateConversion();
				Date now = new Date();
				FileUtil fileUtil = new FileUtil(member.getPhoto().getOriginalFilename());
				String newFileName = dateConversion.ConversionYMDHMS2(now) +"_"+ loginMember.getMemberNO() + "." + fileUtil.getFileType();
				
	        	//rename and move
				File targetFile = new File(path1, newFileName);
		        if(!targetFile.exists()){
		            targetFile.mkdirs();
		        }
		        try {
		        	member.getPhoto().transferTo(targetFile);
		        } catch (Exception e) {
		            e.printStackTrace();
		        }
		        
		        //delete original file
		        if(!oldMember.getPhotoName().equals("") && oldMember.getPhotoType() == 1){
		        	awsUtil.deleteFile(oldMember.getPhotoName());
		        }        	
		        
		        //compress image
				if(!fileUtil.getFileType().equals("gif")){
		    		CompressImage compressImage = new CompressImage();
		        	compressImage.compress(path1+"/", newFileName, 0, 0, false);
		        }				

	        	//upload file AWS
		        try {
					awsUtil.uploadFile("resources/image/picture/", targetFile);
				} catch (FileNotFoundException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
		        
		        //delete local file
		        targetFile.delete();		        

	        	member.setPhotoPath("resources/image/picture/"+newFileName);
	        	member.setPhotoType(1);	
				
			}
			else{
	        	member.setPhotoPath(oldMember.getPhotoName());
	        	member.setPhotoType(oldMember.getPhotoType());
			}
			
			memberDAO.update(member);
			member = memberDAO.get(member);
				
			session.removeAttribute("loginMember");
			session.setAttribute("loginMember", member);
			
			model.setViewName("redirect:/aboutme?id="+oldMember.getMemberNO());

			
		}
		else
			model.setViewName("redirect:/login");
		return model;
 
	}	
	
	@RequestMapping(value = "/resendMail", method = RequestMethod.GET)
	public ModelAndView resendMail() {
		ModelAndView model = new ModelAndView("resendMail");
		List<Menu> menuList = MenuUtil.getList(((MenuDAO)context.getBean("menuDAO")).getList(), 0);
		model.addObject("menuList", menuList);
		return model;
	}
	
	@RequestMapping(value = "/resendConfirmMail", method = RequestMethod.POST)
	public ModelAndView resendConfirmMail(String account, HttpServletRequest request) {
		ModelAndView model = new ModelAndView();
		MemberDAO memberDAO = (MemberDAO) context.getBean("memberDAO");
		Member member = new Member();
		member = memberDAO.checkMember(account);
		if(member.getAccount()!=null && member.getStatus()==0){
			member.setRegisterNO(UUIDGenerator.getUUID());
			memberDAO.updateRegisterNO(member);
			
			HtmlUtil htmlUtil = new HtmlUtil();
			String subject = "Proactive：會員註冊驗證";
			String message = "";
			try {
				message = htmlUtil.htmlToString(request.getServletContext().getRealPath("html/register.html"));
			} catch (FileNotFoundException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			Mail mail = new Mail();
			message = message.replaceAll("link_url", "http://www.proactive.tw/active?aid="+member.getRegisterNO());
			message = message.replaceAll("user_name", member.getName());
			mail.sendMail(subject, member.getAccount(), message);

			model.setViewName("redirect:/register2");
		}
		else 
			model.setViewName("redirect:/resendFail");
		return model;
	}
	
	@RequestMapping(value = "/resendFail", method = RequestMethod.GET)
	public ModelAndView resendFail() {
		ModelAndView model = new ModelAndView("register2");
		List<Menu> menuList = MenuUtil.getList(((MenuDAO)context.getBean("menuDAO")).getList(), 0);
		model.addObject("menuList", menuList);
		model.addObject("flag", false);
		return model;
	}
	
	@RequestMapping(value = "/forgetPassword", method = RequestMethod.GET)
	public ModelAndView forgetPassword(HttpSession session) {
		ModelAndView model = new ModelAndView("forgetPassword");		
		List<Menu> menuList = MenuUtil.getList(((MenuDAO)context.getBean("menuDAO")).getList(), 0);
		model.addObject("menuList", menuList);
		return model;
	}
	
	@RequestMapping(value = "/sendPasswordConfirm", method = RequestMethod.POST)
	public ModelAndView sendPasswordConfirm(String account, HttpServletRequest request) {
		ModelAndView model = new ModelAndView();		
		MemberDAO memberDAO = (MemberDAO) context.getBean("memberDAO");
		Member member = new Member();
		member = memberDAO.checkMember(account);
		if(member.getAccount()!=null && member.getStatus()==1){
			model.setViewName("redirect:/forgetPassword2");
			member.setResetNO(UUIDGenerator.getUUID());
			memberDAO.updateResetNO(member);
			HtmlUtil htmlUtil = new HtmlUtil();
			String subject = "Proactive：忘記密碼";
			String message = "";
			try {
				message = htmlUtil.htmlToString(request.getServletContext().getRealPath("html/forgetPassword.html"));
			} catch (FileNotFoundException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			Mail mail = new Mail();
			message = message.replaceAll("link_url", "http://www.proactive.tw/reset?aid="+member.getResetNO());
			message = message.replaceAll("user_name", member.getName());
			mail.sendMail(subject, member.getAccount(), message);
			
			
			
		}
		else
			model.setViewName("redirect:/forgetPasswordFail");
		return model;
	}
	
	@RequestMapping(value = "/forgetPassword2", method = RequestMethod.GET)
	public ModelAndView forgetPassword2() {
		ModelAndView model = new ModelAndView("forgetPassword2");
		List<Menu> menuList = MenuUtil.getList(((MenuDAO)context.getBean("menuDAO")).getList(), 0);
		model.addObject("menuList", menuList);
		model.addObject("flag", true);
		return model;
	}
	
	@RequestMapping(value = "/forgetPasswordFail", method = RequestMethod.GET)
	public ModelAndView forgetPasswordFail() {
		ModelAndView model = new ModelAndView("forgetPassword2");
		List<Menu> menuList = MenuUtil.getList(((MenuDAO)context.getBean("menuDAO")).getList(), 0);
		model.addObject("menuList", menuList);
		model.addObject("flag", false);
		return model;
	}
	
	@RequestMapping(value = "/reset", method = RequestMethod.GET)
	public ModelAndView reset(String aid) {
		ModelAndView model = new ModelAndView();
		MemberDAO memberDAO = (MemberDAO) context.getBean("memberDAO");
		Member member = new Member();
		member.setResetNO(aid);
		member = memberDAO.getByResetNO(member);
		if(member.getAccount()!=null && member.getStatus()==1){
			List<Menu> menuList = MenuUtil.getList(((MenuDAO)context.getBean("menuDAO")).getList(), 0);
			model.addObject("menuList", menuList);
			model.addObject("aid", aid);
			model.setViewName("reset");
		}
		else
			model.setViewName("redirect:/forgetPasswordFail");
		return model;
	}
	
	@RequestMapping(value = "/resetPassword", method = RequestMethod.POST)
	public ModelAndView resetPassword(String password, String aid) {
		ModelAndView model = new ModelAndView();
		MemberDAO memberDAO = (MemberDAO) context.getBean("memberDAO");
		Member member = new Member();
		SecurityMD5 securityMD5 = new SecurityMD5();
		member.setResetNO(aid);
		member = memberDAO.getByResetNO(member);
		if(member.getAccount()!=null && member.getStatus()==1){
			try {
				password = securityMD5.encryptWords(password);
			} catch (NoSuchAlgorithmException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			member.setPassword(password);
			memberDAO.updatePassword(member);
			model.setViewName("redirect:/reset2");
		}
		else
			model.setViewName("redirect:/forgetPasswordFail");
		return model;
	}
	
	@RequestMapping(value = "/reset2", method = RequestMethod.GET)
	public ModelAndView reset2() {
		ModelAndView model = new ModelAndView("reset2");
		List<Menu> menuList = MenuUtil.getList(((MenuDAO)context.getBean("menuDAO")).getList(), 0);
		model.addObject("menuList", menuList);
		return model;
	}
	
	@RequestMapping(value = "/modiPasswordCont", method = RequestMethod.GET)
	public ModelAndView modiPassowrCont(HttpSession session) {
		ModelAndView model = new ModelAndView();
		Member loginMember = (Member)session.getAttribute("loginMember");
		if(loginMember != null){
			if(loginMember.getRegisterType() == 0){
				boolean flag;
				if(session.getAttribute("flag")!=null){
					flag = (boolean)session.getAttribute("flag");
					session.removeAttribute("flag");
					model.addObject("flag", flag);
				}
				List<Menu> menuList = MenuUtil.getList(((MenuDAO)context.getBean("menuDAO")).getList(), 0);
				model.addObject("menuList", menuList);
				model.setViewName("modiPassword");
			}
			else
				model.setViewName("redirect:/aboutme?id="+loginMember.getMemberNO());
		}
		else
			model.setViewName("redirect:/login");
		return model;
	}
	
	@RequestMapping(value = "/modiPassword", method = RequestMethod.POST)
	public ModelAndView modiPassword(HttpSession session, String password, String oldPassword) {
		ModelAndView model = new ModelAndView();
		MemberDAO memberDAO = (MemberDAO) context.getBean("memberDAO");
		Member loginMember = (Member)session.getAttribute("loginMember");
		SecurityMD5 securityMD5 = new SecurityMD5();
		if(loginMember != null){
			try {
				oldPassword = securityMD5.encryptWords(oldPassword);
				password = securityMD5.encryptWords(password);
			} catch (NoSuchAlgorithmException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			Member member = new Member();
			member.setAccount(loginMember.getAccount());
			member.setPassword(oldPassword);
			member = memberDAO.checkLogin(member);
			if(member.isLogin()){
				member.setPassword(password);
				memberDAO.updatePassword(member);
				session.setAttribute("flag", true);
			}
			else
				session.setAttribute("flag", false);
			model.setViewName("redirect:/modiPasswordCont");
		}
		else
			model.setViewName("redirect:/login");
		return model;
	}
}
